;__CUBPRPB_________________________________________________________________________________________
;
;	PREP THE IDE DRIVE (DRIVE "B") FOR CUBIX
;
;	WRITTEN BY: DAN WERNER -- 12/8/2009
;__________________________________________________________________________________________________
;__________________________________________________________________________________________________
;
; CONFIGURATION
;__________________________________________________________________________________________________
;
;
USEDSKY		.EQU	01		; NONZERO = USE DSKY DEVICE FOR DISK IO STATUS
				
;
;
;__________________________________________________________________________________________________
;
; DATA CONSTANTS
;__________________________________________________________________________________________________
;REGISTER		IO PORT		; FUNCTION
PPIA		.equ	$00		; 8255 PORT A
PPIB		.equ	$01		; 8255 PORT B
PPIC		.equ	$02		; 8255 PORT C
PPICONT		.equ	$03		; 8255 CONTROL PORT 

BDOS		.equ	$0005		; BDOS ENTRY

; IDE REGISTER		IO PORT		; FUNCTION
IDELO:		 .EQU 	20H		; DATA PORT (LOW BYTE)
IDEERR:		 .EQU 	21H		; READ: ERROR REGISTER; WRITE: PRECOMP
IDESECTC:	 .EQU 	22H		; SECTOR COUNT
IDESECTN:	 .EQU 	23H		; SECTOR NUMBER
IDECYLLO:	 .EQU 	24H		; CYLINDER LOW
IDECYLHI:	 .EQU 	25H		; CYLINDER HIGH
IDEHEAD:	 .EQU 	26H		; DRIVE/HEAD
IDESTTS:	 .EQU 	27H		; READ: STATUS; WRITE: COMMAND
IDEHI:		 .EQU 	28H		; DATA PORT (HIGH BYTE)
IDECTRL:	 .EQU 	2EH		; READ: ALTERNATIVE STATUS; WRITE; DEVICE CONTROL
IDEADDR:	 .EQU 	2FH		; DRIVE ADDRESS (READ ONLY)
CR		.EQU	$0D		; CARRIAGE RETURN CHARACTER
LF		.EQU	$0A		; LINE FEED CHARACTER
END		.EQU	'$'		; LINE TERMINATOR FOR CP/M STRINGS
FMSR:		 .EQU	036H		; ADDRESS OF MAIN STATUS REGISTER
FDATA:		 .EQU	037H		; FLOPPY DATA REGISTER
FLATCH:		 .EQU	03AH		; FLOPPY CONFIGURATION LATCH
FDMA:		 .EQU	03CH		; PSEUDO DMA ADDRESS
;
; FDC CONFIGURATION LATCH OUTPUT BIT PATTERNS
MOTOR:		 .EQU	00000000b	; BIT PATTERN IN LATCH FOR MOTOR CONTROL (ON)
TERMCN:		 .EQU	00000001b	; BIT PATTERN IN LATCH TO WRITE A TC STROBE
RESETL:		 .EQU	00000010b	; BIT PATTERN IN LATCH TO RESET ALL BITS
MINI:		 .EQU	00000100b	; BIT PATTERN IN LATCH TO SET MINI MODE FDC9229 LOW DENS=1, HIGH DENS=0
PRECOMP:	 .EQU	00100000b	; BIT PATTERN IN LATCH TO SET WRITE PRECOMP 125 NS:
FDDENSITY:	 .EQU	01000000b	; BIT PATTERN IN LATCH TO FLOPPY LOW DENSITY (HIGH IS 0)
FDREADY:	 .EQU	10000000b	; BIT PATTERN IN LATCH TO FLOPPY READY (P-34):




	.org	$0100


;__________________________________________________________________________________________________
;
; 	MAIN 
;__________________________________________________________________________________________________
MAIN:
	CALL	SETUPDRIVE
					; BLANK OUT FIRST 6 SECTORS
	LD	HL,SECTOR_BUFFER	;
	LD	BC,$0200		;
	LD	A,$00			;
	CALL	FILL_MEM		;
	
	
	LD	A,$00			;
	LD	(SECTOR),A		;
	LD	(HEAD),A		;
	LD	(TRACK),A		;
MAIN_1:
	CALL	WRITE_0			;
	LD	A,(SECTOR)		;
	ADD	A,1			;
	LD	(SECTOR),A		;
	CP	$06			;
	JP	NZ,MAIN_1		;

	LD	HL,SECTOR_BUFFER	;
	LD	BC,$0000		;	

	
	LD	A,$0FF			;
	LD	(SECTOR_BUFFER),A	;
	LD	(SECTOR_BUFFER+1),A	;
	LD	(SECTOR_BUFFER+$0A),A	;
	LD	(SECTOR_BUFFER+$0B),A	;
	LD	A,$00			;
	LD	(SECTOR_BUFFER+2),A	;
	LD	(SECTOR_BUFFER+4),A	;
	LD	(SECTOR_BUFFER+6),A	;
	LD	(SECTOR_BUFFER+8),A	;
	LD	A,$02			;
	LD	(SECTOR_BUFFER+3),A	;
	LD	A,$03			;
	LD	(SECTOR_BUFFER+5),A	;
	LD	A,$04			;
	LD	(SECTOR_BUFFER+7),A	;
	LD	A,$05			;
	LD	(SECTOR_BUFFER+9),A	;


	LD	A,$01			;
	LD	(SECTOR),A		;
	LD	A,$00			;
	LD	(HEAD),A		;
	LD	(TRACK),A		;
	CALL	WRITE_0			;
	

	
	LD	DE,MSG_END		;
	LD	C,09H			; CP/M WRITE END STRING TO CONSOLE CALL
	CALL	0005H			;
					;
	LD	C,00H			; CP/M SYSTEM RESET CALL
	CALL	0005H			; RETURN TO PROMPT

MSG_END:
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.TEXT	"END CUBIX ZIP PREP PROGRAM"
	.DB	LF, CR			; LINE FEED AND CARRIAGE RETURN
	.DB	END			; LINE TERMINATOR


	
;__WRITE_0__________________________________________________________________________________________ 
;
;	WRITE A SECTOR TO DRIVE 0
;___________________________________________________________________________________________________
;
WRITE_0:
	CALL	SETTRACK		;
	CALL	FLOPPYWRITE		;
	
	LD	A,(ST0)			; GET STATUS FLAG 0
	AND	0F8H			; MASK OF DRIVE AND HEAD SELECTION
	LD	B,A			; MOVE STATUS FLAG 0 TO B
	LD	A,(ST1)			; GET STATUS FLAG 1
	OR	B			; IF ZERO READ WAS OK
	JP	NZ,WRITE_0		;
	RET

		
;__FILL_MEM______________________________________________________________________________________________________________________ 
;
;	Function	: fill memory with a value
;      	Input		: HL = start address block
;			: BC = length of block
;			: A = value to fill with
;	Uses		: DE, BC
;________________________________________________________________________________________________________________________________
;

FILL_MEM:

					; HL = start address of block
					; DE = HL + 1
	ld	e,l			;
	ld	d,h			;
	inc	de			;
					; initialise first byte of block
					; with data byte (&00)
					; with data byte in A
	ld	(hl),A			;
	ldir				;
	RET				; return to caller
		
	
;__SETUPDRIVE__________________________________________________________________________________________________________________________ 
;
;	SETUP FLOPPY DRIVE SETTINGS 
;________________________________________________________________________________________________________________________________
;
;
;
SETUPDRIVE:
	LD	A,RESETL		; RESET SETTINGS
	OR	MINI			; SELECT MINI FLOPPY (LOW DENS=1, HIGH DENS=0)
	OR	PRECOMP			; SELECT PRECOMP 
	OR	FDDENSITY		; SELECT DENSITY
	OR	FDREADY			; SELECT READY SIGNAL
	LD	(FLATCH_STORE),A	; SAVE SETTINGS
	LD	A,01H			;
	LD	(UNIT),A		; SET UNIT 1
	LD	A,2			; DENSITY
	LD	(DENS),A		;
	LD	A,09			;
	LD	(EOTSEC),A		; LAST SECTOR OF TRACK			
	LD	A,7FH			;
	LD	(SRTHUT),A		; STEP RATE AND HEAD UNLOAD TIME
	LD	A,05H			;
	LD	(HLT),A			; HEAD LOAD TIME
	LD	A,0DH			;
	LD	(GAP),A			; GAP 
	LD	A,80H			;
	LD	(SECSIZ),A		; SECTOR SIZE /4
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
					;					
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				;
	LD	A,00H			; ZERO TRACK
	LD	(TRACK),A		; STORE TRACK
	CALL	SETTRACK		; DO IT	
	NOP				;
	NOP				;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	RET
;
;__OUTFLATCH__________________________________________________________________________________________________________________________ 
;
;	SEND SETTINGS TO FLOPPY CONTROLLER
;________________________________________________________________________________________________________________________________
;
OUTFLATCH:
	LD	A,(FLATCH_STORE)	; SET A TO SETTINGS
	OUT	(FLATCH),A		; OUTPUT TO CONTROLLER
	RET

		
;__FLOPPYREAD__________________________________________________________________________________________________________________________ 
;
; 	READ A FLOPPY DISK SECTOR 	
;________________________________________________________________________________________________________________________________
;	
FLOPPYREAD:
	.IF	USEDSKY
	CALL	SEGDISPLAY		;
	.ENDIF
	LD	A,46H			; BIT 6 SETS MFM, 06H IS READ COMMAND
	LD	(CMD),A			;
	JP	DSKOP			;
;
;__FLOPPYWRITE__________________________________________________________________________________________________________________________ 
;
; 	WRITE A FLOPPY DISK SECTOR 	
;________________________________________________________________________________________________________________________________
;	
FLOPPYWRITE:
	.IF	USEDSKY
	CALL	SEGDISPLAY		;
	.ENDIF
	LD	A,45H			; BIT 6 SETS MFM, 05H IS WRITE COMMAND
	LD	(CMD),A			;
	JP	DSKOP			;
;
;__DSKOP__________________________________________________________________________________________________________________________ 
;
; 	PERFORM A DISK OPERATION 	
;________________________________________________________________________________________________________________________________
;		
DSKOP:
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	CP	0FFH			; DID IT RETURN WITH ERROR CODE?
	JP	Z,DSKEXIT		; IF YES, EXIT WITH ERROR CODE
					;	
	LD	A,(UNIT)		; GET DISK UNIT NUMBER
	AND	03H			; MASK FOR FOUR DRIVES 
	LD	B,A			; PARK IT IN B
	LD	A,(FHEAD)		; GET HEAD SELECTION
	AND	01H			; INSURE SINGLE BIT
	RLA				;
	RLA				; MOVE HEAD TO BIT 2 POSITION
	OR	B			; OR HEAD TO UNIT BYTE IN COMMAND BLOCK
	LD	(UNIT),A		; STORE IN UNIT
					;
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	RES	1,(HL)			; SET MOTOR ON
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER	
					;
	LD	A,03H			; SPECIFY COMMAND
	CALL	PFDATA			; PUSH IT
	LD	A,(SRTHUT)		; STEP RATE AND HEAD UNLOAD TIME
	CALL	PFDATA			; PUSH THAT
	LD	A,(HLT)			;
	CALL	PFDATA			; PUSH THAT
					;
	CALL	SETTRACK		; PERFORM SEEK TO TRACK
					;
	JP	NZ,DSKEXIT		; IF ERROR, EXIT
					;
	LD	A,(CMD)			; WHAT COMMAND IS PENDING?
	OR	A			; SET FLAGS
	JP	DOSO4			; NO, MUST BE READ OR WRITE COMMAND
DSKEXIT:	
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	OR	0FFH			; SET -1 IF ERROR
	RET

RESULT:
	LD	C,07H			; LOAD C WITH NUMBER OF STATUS BYTES
	LD	HL,ST0			; POINT TO STATS STORAGE
RS3:
	CALL	GFDATA			; GET FIRST BYTE
	LD	(HL),A			; SAVE IT
	INC	HL			; POINTER++
	DEC	C			; CC-1
	JP	NZ,RS3			; LOOP TIL C0
	LD	A,(ST0)			; LOAD STS0
	AND	0F8H			; MASK OFF DRIVE #
	LD	B,A			; PARK IT
	LD	A,(ST1)			; LOAD STS1
	OR	B			; ACC OR B ->ACC IF 0 THEN SUCCESS
					;
RSTEXIT:
	CALL	CHECKINT		; CHECK INTERRUPT STATUS, MAKE SURE IT IS CLEAR
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	1,(HL)			; SET MOTOR OFF
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
					;
	.IF	USEDSKY					
	CALL	SEGDISPLAY		;
	.ENDIF
	RET				; DONE RETURN TO CALLER 
	
	
DOSO4:
					;
	LD	HL,SECTOR_BUFFER	; GET BUFFER ADDRESS TO HL
	LD	A,(SECSIZ)		; XFERLEN
	LD	C,A			; C WILL BE THE NUMBER OF TRANSACTIONS
					; DIVIDED BY 4
					;
	LD	A,(CMD)			;
	CALL	PFDATA			; PUSH COMMAND TO I8272
	LD	A,(UNIT)		;
	CALL	PFDATA			; 
	LD	A,(TRACK)		;
	CALL	PFDATA			; 
	LD	A,(FHEAD)		;
	CALL	PFDATA			; 
	LD	A,(SECTOR)		;
	INC	A			;
	CALL	PFDATA			; 
	LD	A,(DENS)		;
	CALL	PFDATA			; WHAT DENSITY
	LD	A,(EOTSEC)		;
	CALL	PFDATA			; ASSUME SC (SECTOR COUNT)  EOT
	LD	A,(GAP)			;
	CALL	PFDATA			; WHAT GAP IS NEEDED
	LD	A,(DTL)			; DTL, IS THE LAST COMMAND BYTE TO I8272
	CALL	PFDATAS
	LD	A,(CMD)			; READ IS 0 IS THIS A READ OR WRITE?
	AND	000000001b		; WRITE IS 1
	JP	NZ,WRR			; JMP WRITE IF 1
;

	;
; PERFORM READ
; LOOP EXECUTES 4X, THIS ALLOWS C RATHER THAN BC AS COUNTER
; SAVING A FEW TSTATES  MAKES UP TO 1024 BYTE SECTORS POSSIBLE.
; FROM READ TO READ MUST NOT EXCEED 25US WORST CASE MIN 
; (76T STATES FOR 3MHZ 8085) OR (100 T STATES FOR 4MHZ Z80)
;

RDD_POLL:
FDC_READP0:
	IN	A,(FMSR)		;
	OR	A			; TEST IF BYTE READY RQM1
	JP	P,FDC_READP0		;	
					;
	AND	20H			;
	JP	Z,DSKOPEND		;JUMP IF IN RESULTS MODE
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;

FDC_READP1:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP1		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP2:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_READP2		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	IN	A,(FDATA)		;
	LD	(HL),A			;
	INC	HL			;
					;
FDC_READP3:
	IN	A,(FMSR)		; 11
	OR	A			; 4
	JP	P,FDC_READP3		; 10
					;
	AND	20H			; 7
	JP	Z,DSKOPEND		; 10
					;
	IN	A,(FDATA)		; 11
	LD	(HL),A			; 10
	INC	HL			; 11
					;
	DEC	C			; 4
	JP	NZ,FDC_READP0		; 11

DSKOPEND:
	LD	HL,FLATCH_STORE		; POINT TO FLATCH
	SET	0,(HL)			; SET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	RES	0,(HL)			; RESET TC
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	NOP				;
	NOP				; 2 MICROSECOND DELAY
	SET	1,(HL)			; TURN OFF MOTOR
	CALL	OUTFLATCH		; OUTPUT TO CONTROLLER
	JP	RESULT			; GET STATUS BYTES <RESULT PHASE>
WRR:
FDC_WRITEP0:
	IN	A,(FMSR)		;
	OR	A			; TEST IF BYTE READY RQM1
	JP	P,FDC_WRITEP0		;	
					;
	AND	20H			;
	JP	Z,DSKOPEND		;JUMP IF IN RESULTS MODE
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;

FDC_WRITEP1:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_WRITEP1		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;
					;
FDC_WRITEP2:
	IN	A,(FMSR)		;
	OR	A			;
	JP	P,FDC_WRITEP2		;
					;
	AND	20H			;
	JP	Z,DSKOPEND		;
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			;
					;
FDC_WRITEP3:
	IN	A,(FMSR)		; 11
	OR	A			; 4
	JP	P,FDC_WRITEP3		; 10
					;
	AND	20H			; 7
	JP	Z,DSKOPEND		; 10
					;
	LD	A,(HL)			;
	OUT	(FDATA),A		;	
	INC	HL			; 11
					;
	DEC	C			; 4
	JP	NZ,FDC_WRITEP0		; 11
	JP	DSKOPEND		; 10
	
		
;__SETTRACK__________________________________________________________________________________________________________________________ 
;
; 	SEEK TO A TRACK ON GIVEN UNIT
; 	A: TRACK #
;________________________________________________________________________________________________________________________________
;
SETTRACK:
	LD	A,(TRACK)		; GET TRACK
	OR	A			; SET FLAGS
	JP	Z,RECAL			; IF 0 PERFORM RECAL INSTEAD OF SEEK
	LD	(TRACK),A		; STORE TRACK
	LD	A,0FH			; SEEK COMMAND
	CALL	PFDATA			; PUSH COMMAND
	LD	A,(UNIT)		; SAY WHICH UNIT
	CALL	PFDATA			; SEND THAT
	LD	A,(TRACK)		; TO WHAT TRACK
	CALL	PFDATA			; SEND THAT TOO
	JP	WAINT			; WAIT FOR INTERRUPT SAYING DONE
RECAL:
	LD	A,00H			;
	LD	(TRACK),A		; STORE TRACK
	LD	A,07H			; RECAL TO TRACK 0
	CALL	PFDATA			; SEND IT
	LD	A,(UNIT)		; WHICH UNIT
	CALL	PFDATA			; SEND THAT TOO
;
WAINT:
;
	CALL	DELAYHSEC		; DELAY TO LET HEADS SETTLE BEFORE READ
					;
					; WAIT HERE FOR INTERRPT SAYING DONE
					; LOOP TIL INTERRUPT
	CALL	CHECKINT		; CHECK INTERRUPT STATUS
;
	RET
	
;__PFDATAS__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER S EQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATAS:
	PUSH	AF			; STORE AF
PFDS1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFDS1			; WAIT FOR RQM TO BE TRUE 
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	RET		
	
;__PFDATA__________________________________________________________________________________________________________________________ 
;
; WRITE A COMMAND OR PARAMETER S EQUENCE
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;
PFDATA:
	PUSH	AF			; STORE AF
PFD1:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT 
	JP	Z,PFD1			; WAIT FOR RQM TO BE TRUE 
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	CALL	NZ,ERRORT		; NO, SIGNAL ERROR
	POP	AF			; RESTORE AF
	OUT	(FDATA),A		; OUTPUT A TO CONTROLLER
	JP	DELAY24			; DELAY 24US
	
	
	
;__DELAY24__________________________________________________________________________________________________________________________ 
;
; 	DELAY 24US
;________________________________________________________________________________________________________________________________
;
	
DELAY24:	
					; JP= 10T	
	PUSH	IX			; 15T
	POP	IX			; 14T
	PUSH	IX			; 15T
	POP	IX			; 14T
DELAY12:
	PUSH	IX			; 15T
	POP	IX			; 14T
	RET				; 10T


;__CHECKINT__________________________________________________________________________________________________________________________ 
;
; CHECK FOR ACTIVE FDC INTERRUPTS BEFORE GIVING I8272 COMMANDS
; POLL RQM FOR WHEN NOT BUSY AND THEN SEND FDC
; SENSE INTERRUPT COMMAND   IF IT RETURNS WITH NON ZERO
; ERROR CODE, PASS BACK TO CALLING ROUTINE FOR HANDLING
;________________________________________________________________________________________________________________________________
;
CHECKINT:
	IN	A,(FMSR)		; READING OR WRITING IS KEYS TO D7 RQM
	AND	80H			; MASK OFF RQM BIT
	JP	Z,CHECKINT		; WAIT FOR RQM TO BE TRUE  WAIT UNTIL DONE
	IN	A,(FMSR)		; READ STATUS
	AND	40H			; WAITING FOR INPUT?
	JP	NZ,CHECKINTDONE		; NO, SIGNAL ERROR
	CALL	SENDINT			; SENSE INTERRUPT COMMAND
CHECKINTDONE:
	RET				;
	

;__DELAYHSEC__________________________________________________________________________________________________________________________ 
;
; DELAY FOR 1/2 SECOND
;________________________________________________________________________________________________________________________________
;		
DELAYHSEC:
	LD	HL,00000H		; 65536
DELDM:
	NOP				; (4 T) 
	NOP				; (4 T)
	NOP				; (4 T)
	NOP				; (4 T)
	DEC	L			; (6 T)
	JP	NZ,DELDM		; (10 T) 24 T  8 MICROSECONDS AT 4 MHZ
	DEC	H			; (6 T)
	JP	NZ,DELDM		; (10 T) (8 US * 256) * 256  524288 US   5 SECONDS
	RET

;__ERRORT__________________________________________________________________________________________________________________________ 
;
; ERROR HANDLING
;________________________________________________________________________________________________________________________________
;			
ERRORT:
	IN	A,(FDATA)		; CLEAR THE JUNK OUT OF DATA REGISTER
	IN	A,(FMSR)		; CHECK WITH RQM
	AND	80H			; IF STILL NOT READY, READ OUT MORE JUNK
	JP	Z,ERRORT		;
	LD	A,0FFH			; RETURN ERROR CODE -1
					;
	RET
;__SENDINT__________________________________________________________________________________________________________________________ 
;
; SENSE INTERRUPT COMMAND
;________________________________________________________________________________________________________________________________
;			
SENDINT:
	LD	A,08H			; SENSE INTERRUPT COMMAND
	CALL	PFDATA			; SEND IT
	CALL	GFDATA			; GET RESULTS
	LD	(ST0A),A		; STORE THAT
	AND	0C0H			; MASK OFF INTERRUPT STATUS BITS
	CP	80H			; CHECK IF INVALID COMMAND
	JP	Z,ENDSENDINT		; YES, EXIT
	CALL	GFDATA			; GET ANOTHER (STATUS CODE 1)
	LD	(ST1A),A		; SAVE THAT
	LD	A,(ST0A)		; GET FIRST ONE
	AND	0C0H			; MASK OFF ALL BUT INTERRUPT CODE 00 IS NORMAL
ENDSENDINT:
	RET				;ANYTHING ELSE IS AN ERROR


;__GFDATA__________________________________________________________________________________________________________________________ 
;
; GET DATA FROM FLOPPY CONTROLLER
;
; TRANSFERS ARE SYNCHONIZED BYT MSR D7 <RQM> AND D6 <DIO>
;	RQM  DIO
;	0	0	BUSY
;	1	0	WRITE TO DATA REGISTER PERMITTED
;	1	1	BYTE FOR READ BY HOST PENDING
;	0	1	BUSY
;
;________________________________________________________________________________________________________________________________
;		
GFDATA:
	IN	A,(FMSR)		; READ STATUS BYTE
	AND	80H			; MASK OFF RQM
	JP	Z,GFDATA		; LOOP WHILE BUSY
	IN	A,(FMSR)		; READ STSTUS BUTE
	AND	40H			; MASK OFF DIO
	CALL	Z,ERRORT		; IF WRITE EXPECTED RUN ERRORRT
	IN	A,(FDATA)		; READ DATA
	JP	DELAY24			; DELAY 24US
	

; PIO 82C55 I/O IS DECODED TO PORT 60-67
;
PORTA		 .EQU 	60H
PORTB		 .EQU 	61H
PORTC		 .EQU 	62H
PIOCONT 	 .EQU 	63H	

;__IDESEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF IDE LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
IDESEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(IDE_LBA3)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(IDE_LBA3)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(IDE_LBA2)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(IDE_LBA2)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(IDE_LBA1)		;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(IDE_LBA1)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(IDE_LBA0)		;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(IDE_LBA0)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	JP	SEGDISPLAY1		;
;__ATAPISEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF ATAPI LOGICAL BLOCK ADDRESS ON DSKY    
;____________________________________________________________________________________________________
ATAPISEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
					;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(LBA_TARGET_HI+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;
					;
	LD	A,(LBA_TARGET_HI)	;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(LBA_TARGET_HI)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
					;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(LBA_TARGET_LO+1)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;
	
	LD	A,(LBA_TARGET_LO)	;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(LBA_TARGET_LO)	;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
	JP	SEGDISPLAY1		;

;__SEGDISPLAY________________________________________________________________________________________
;
;  DISPLAY CONTENTS OF TRACK, SECTOR, ST0, ST1 ON DSKY
;     
;____________________________________________________________________________________________________
SEGDISPLAY:
	LD	A, 82H			;
	OUT (PIOCONT),A			;
	LD	A,(TRACK)		;
	AND	0FH			;
	LD	(DISPLAYBUF+6),A	;
	LD	A,(TRACK)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+7),A	;			
	LD	A,(SECTOR)		;
	AND	0FH			;
	LD	(DISPLAYBUF+4),A	;
	LD	A,(SECTOR)		;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+5),A	;
	LD	A,(ST0)			;
	AND	0FH			;
	LD	(DISPLAYBUF+2),A	;
	LD	A,(ST0)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+3),A	;			
	LD	A,(ST1)			;
	AND	0FH			;
	LD	(DISPLAYBUF),A		;
	LD	A,(ST1)			;
	AND	0F0H			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	SRL	A			;
	LD	(DISPLAYBUF+1),A	;
SEGDISPLAY1:				;
	LD	HL,DISPLAYBUF		;
	LD	BC,0007H		;
	ADD	HL,BC			;
	LD	B,08H			; SET DIGIT COUNT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
	LD	A,0D0H			; SET CONTROL TO 1111 (DATA COMING, HEX DECODE, DECODE, NORMAL)
	OUT	(PORTA),A		; OUTPUT TO PORT
	LD	A,80H			; STROBE WRITE PULSE WITH CONTROL=1
	OUT	(PORTC),A		; OUTPUT TO PORT
	CALL 	DELAY12			; WAIT
	LD	A,40H			; SET CONTROL PORT 7218 TO OFF
	OUT	(PORTC),A		; OUTPUT
	CALL 	DELAY12			; WAIT
SEGDISPLAY_LP:		
	LD	A,(HL)			; GET DISPLAY DIGIT
	OUT	(PORTA),A		; OUT TO PORTA
	LD	A,00H			; SET WRITE STROBE
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; DELAY
	LD	A,40H			; SET CONTROL PORT OFF
	OUT	(PORTC),A		; OUT TO PORTC
	CALL	DELAY12			; WAIT
	DEC	HL			; INC POINTER
	DJNZ	SEGDISPLAY_LP		; LOOP FOR NEXT DIGIT
	RET	
	
DISPLAYBUF:	 .DB 	01,02,03,04,05,06,07,08
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
		 .DB	00,00,00,00,00,00,00,00	
FLOPPYSTACK:	 .DB	00
PARKSTACK:	 .DB	00,00,00,00
		
READ_DISK_PACKET
		 .DB	0A8H,00,00,00,00,01H,00,00,00,01H,00,00
WRITE_DISK_PACKET
		 .DB	2AH,00,00,00,00,11H,00,00,01H,00,00,00
ATAPI_REQUEST_SENSE
		 .DB	03H,00,00,00,011H,00,00,00,00,00,00,00

;
; DISK COMMAND BLOCK
;
CMD:		 .DB	0			; COMMAND READ OR WRITE,
UNIT:		 .DB	0			; PHYSICAL DRIVE 0->3
FHEAD:		 .DB	0			; HEAD SEL 0 OR 1
DENS:		 .DB	2			; DENSITY
EOTSEC:		 .DB	09			; LAST SECTOR OF TRACK
GAP:		 .DB	1BH			; VALUE FOR IRG <GAP3>
SECSIZ:		 .DB	080H			; HOW MANY BYTES TO TRANSFER/4
DTL:		 .DB	0FFH			; SIZE OF SECTOR
SRTHUT:		 .DB	7FH			; STEP RATE AND HEAD UNLOAD TIME
HLT:		 .DB	05H			; HEAD LOAD TIME
MIN:		 .DB	MINI			; LATCH BIT PATTERN FOR FDC9229 MINITRUE
PRE:		 .DB	PRECOMP			; LATCH BIT PATTERN FOR FDC9229 PRECOMP125NS
;
; FLOPPY STATUS RESULT STORAGE
;
ST0:		.DB	0			; STORE STATUS 0
ST1:		.DB	0			; ST1
ST2:		.DB	0			; ST2
SCYL:		.DB	0			; TRACK
SHEAD:		.DB	0			; HEAD 0 OR 1
SREC:		.DB	0			; SECTOR
SNBIT:		.DB	0			; DENSITY
ST0A:		.DB	0			; STORE STATUS 0
ST1A:		.DB	0			; ST1
RETRY		.DB	0			; RETRIES
RETRY1		.DB	0			; RETRIES

FLATCH_STORE:	.DB	00

CPMSTART	.DW	00			; START OF CP/M
DRIVE		.DB	0			; DRIVE
TRACK		.DB 	0			; TRACK
HEAD		.DB	0			; HEAD
SECTOR		.DB	0			; SECTOR
LBA_TARGET_LO:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (LOW 16 BITS)
LBA_TARGET_HI:	.DW 	0			; IDE HD PARTITION TARGET SECTOR (HI 16 BITS, 12 USED)
IDEDEVICE:	.DB 	0			; ATAPI DEVICE SELECTION FLAG

IDE_LBA0:	.DB 	0			; SET LBA 0:7
IDE_LBA1:	.DB 	0			; SET LBA 8:15
IDE_LBA2:	.DB 	0			; SET LBA 16:23
IDE_LBA3:	.DB 	0			; LOWEST 4 BITS USED ONLY TO ENABLE LBA MODE 
;
SECTOR_BUFFER:	.DS 520				; STORAGE FOR 512 BYTE IDE HD SECTOR

		
	
	
	
	
;__HXOUT_________________________________________________________________________________________________________________________ 
;
;	PRINT THE ACCUMULATOR CONTENTS AS HEX DATA ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
HXOUT:
	PUSH	BC			; SAVE BC
	LD	B,A			;
	RLC	A			; DO HIGH NIBBLE FIRST  
	RLC	A			;
	RLC	A			;
	RLC	A			;
	AND	0FH			; ONLY THIS NOW
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT1			; IF CY SET PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT AN ALPHA
OUT1:
	CALL	COUT			; SCREEN IT
	LD	A,B			; NEXT NIBBLE
	AND	0FH			; JUST THIS
	ADD	A,30H			; TRY A NUMBER
	CP	3AH			; TEST IT
	JR	C,OUT2			; PRINT 'NUMBER'
	ADD	A,07H			; MAKE IT ALPHA
OUT2:
	CALL	COUT			; SCREEN IT
	POP	BC			; RESTORE BC
	RET				;


;__SPACE_________________________________________________________________________________________________________________________ 
;
;	PRINT A SPACE CHARACTER ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
SPACE:
	PUSH	AF			; Store AF
	LD	A,20H			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__CRLF_________________________________________________________________________________________________________________________ 
;
;	PRINT A cr/lf
;________________________________________________________________________________________________________________________________
;
CRLF:
	PUSH	AF			; Store AF
	LD	A,0DH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	LD	A,0AH			; LOAD A "SPACE"
	CALL	COUT			; SCREEN IT
	POP	AF			; RESTORE AF
	RET				; DONE

;__COUT_________________________________________________________________________________________________________________________ 
;
;	PRINT CONTENTS OF A 
;________________________________________________________________________________________________________________________________
;
COUT:
	PUSH	BC			;
	PUSH	AF			;
	PUSH	HL			;
	PUSH	DE			;
		
	LD	(COUT_BUFFER),A		;
	LD	DE,COUT_BUFFER		;
	LD	C,09H			; CP/M WRITE START STRING TO CONSOLE CALL
	CALL	0005H
	POP	DE			;
	POP	HL			;
	POP	AF			;
	POP	BC			;
	RET				; DONE




;__PHL_________________________________________________________________________________________________________________________ 
;
;	PRINT THE HL REG ON THE SERIAL PORT
;________________________________________________________________________________________________________________________________
;
PHL:
	LD	A,H			; GET HI BYTE
	CALL	HXOUT			; DO HEX OUT ROUTINE
	LD	A,L			; GET LOW BYTE
	CALL	HXOUT			; HEX IT
	CALL	SPACE			; 
	RET				; DONE  

COUT_BUFFER:
	.DB	00
	.DB	"$"

	.end
	